﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Nage.Algorithms.Solution;
using Nage.Algorithms.Population;
using Nage.Algorithms.Stop;
using Nage.Algorithms.Evolution;
using Utils.Logger;

namespace Nage.Algorithms
{
    /// <summary>
    /// Genetic algorithm base class
    /// </summary>
    /// <typeparam name="TSol">type of solution</typeparam>
    public abstract class GeneticAlgorithmBase<TSol> where TSol : ISolution
    {
        #region Public properties

        /// <summary>
        /// Population Factory
        /// </summary>
        public IPopulationFactory<TSol> PopulationFactory { get; set; }

        /// <summary>
        /// Solution Evaluator
        /// </summary>
        public ISolutionEvaluator<TSol> SolutionEvaluator { get; set; }

        /// <summary>
        /// Stop Condition
        /// </summary>
        public IStopCondition StopCondition { get; set; }

        /// <summary>
        /// Evolution
        /// </summary>
        public IEvolution<TSol> Evolution { get; set; }

        /// <summary>
        /// Indicates whether or not each population should be saved
        /// and later accessible by GetStepList method
        /// </summary>
        public Boolean RegisterEachStep { get; set; }

        #endregion

        #region Initialize
        /// <summary>
        /// Checks initial parameters
        /// </summary>
        protected virtual void Initialize()
        {
            CLogger.LogDebug("GeneticAlgorithm -> Initialize");
            if (PopulationFactory == null)
            {
                throw new ArgumentException("PopulationFactory");
            }
            if (SolutionEvaluator == null)
            {
                throw new ArgumentException("SolutionEvaluator");
            }
            if (StopCondition == null)
            {
                throw new ArgumentException("StopCondition");
            }
            if (Evolution == null)
            {
                throw new ArgumentException("Transformation");
            }
        }
        #endregion
    }
}
